
#include <stdint.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>


static uint8_t*pcm = 0;
static int pcm_len = 0;
static int lock = 0;

typedef struct{
    uint8_t* pcm;
    int write_offset;
    int cur_w_offset;
    int read_offset;
    int allocSize;
    int rwrite;
}Wave;

static Wave wave;

static void init(Wave*w){
    w->allocSize = 1024*1024*2;
    w->pcm = calloc(1,w->allocSize+1024*1024*2);
    w->write_offset = 0;
    w->read_offset = 0;
}

static void write(Wave*w,void*data,int size){
    //写入偏移的pcm数据中
    uint8_t*pcm = w->pcm+w->write_offset;
    //如果没有到尾部
    if((w->write_offset+size)<w->allocSize){
        memcpy(pcm,data,size);
        w->write_offset += size;
        w->cur_w_offset += size;
    }
    else{
        //已经到尾部,从头开始写起
        memcpy(pcm,data,w->allocSize-w->write_offset);
        size -= w->allocSize-w->write_offset;
        pcm = w->pcm + 0;
        memcpy(pcm,data,size);
        w->write_offset = size;
        w->cur_w_offset += size;
    }
}

static void read(volatile Wave*w,void*data,int size){
    //printf("wr:%d\n%d\n",w->read_offset,w->write_offset);
    if(w->read_offset>=w->cur_w_offset){
        return;
    }
    else if(w->read_offset+size>=w->cur_w_offset){
        //如果未饱满,则退出
        printf("nowrte\n",w->read_offset,w->write_offset);
        return;
    }
    else if(w->read_offset+size<(w->cur_w_offset-16384*2)){
        //如果速度过快

        if(w->cur_w_offset>w->write_offset){
            w->read_offset = 0;
            w->cur_w_offset = w->write_offset;
            printf("-----fast speed%d  :%d  :%d \n",w->cur_w_offset,size,w->read_offset);
            return;
        }
        else{
            w->read_offset = w->cur_w_offset - size - 16384*2;
        }
        printf("fast speed%d  :%d  :%d \n",w->cur_w_offset,size,w->read_offset);
    }
    //偏移后的pcm
    uint8_t*pcm = w->pcm+w->read_offset;
    if(size+w->read_offset<=w->allocSize){
        memcpy(data,pcm,size);
        w->read_offset += size;
    }
    else{
        //从头复制
        memcpy(data,pcm,w->allocSize-w->read_offset);
        size = w->allocSize - w->read_offset;
        pcm = w->pcm + 0;
        memcpy(data,pcm,size);
        printf("rea");
        w->read_offset = size;
        w->cur_w_offset = w->write_offset;
    }
}


int SDLWritePCM(uint8_t*wave_data,int len){
    if(!wave.pcm)
        init(&wave);

    while(lock)
        ;
    write(&wave,wave_data,len);
    return 0;
}

void SDLSoundCallBack(void*userdata,uint8_t*stream,int len){
    if(!wave.pcm)
        init(&wave);
    read(&wave,stream,len);
}

